﻿using System;
using System.Threading.Tasks;

namespace Task枚举CreationOptions
{
    class Program
    {
        static void Main(string[] args)
        {
            /****
             * TaskCreationOptions.AttachedToParent 枚举  
             *     建立父子关系，父任务想要继续执行必须等待子任务执行完毕，类似 
             * TaskCreationOptions.DenyChildAttach
             *      阻止子任务附加到父任务，和上面一样
             *TaskCreationOptions.HideScheduler
             *      子任务默认不使用父任务的task的schedule，而是使用默认的
             * TaskCreationOptions.LongRunning
             *      如果你明知道是长时间运行的任务，就选择这个，建议使用thread而不是threadpool
             *      线程池 的线程是有限的，如果长时间使用不还，会导致线程池中的线程太多，
             *      销毁和调度 增加开销， 查看源码 ThreadPoolTaskScheduler : TaskScheduler，可以看到如果是 longrunning 就直接使用了thread
             *      protected internal override void QueueTask(Task task)
		            {
			            if ((task.Options & TaskCreationOptions.LongRunning) != TaskCreationOptions.None)
			            {
				            new Thread(ThreadPoolTaskScheduler.s_longRunningThreadWork)
				            {
					            IsBackground = true
				            }.Start(task);
				            return;
			            }
			            bool forceGlobal = (task.Options & TaskCreationOptions.PreferFairness) > TaskCreationOptions.None;
			            ThreadPool.UnsafeQueueCustomWorkItem(task, forceGlobal);
		            }
             *TaskCreationOptions.PreferFairness
             *      给人一种队列的感觉，就是早安排早执行，会将task放入到ThreadPool的全局队列中，
             *      让work争夺，默认情况下会放在线程下一个本地队列
             * 
             *      
             * *********/

            var task0 =new Task(()=> {
                var task1 = new Task(() => {
                    Console.WriteLine("task1");
                }, TaskCreationOptions.AttachedToParent);
                var task2 = new Task(() => {
                    Console.WriteLine("task2");
                }, TaskCreationOptions.AttachedToParent);

                task1.Start();
                task2.Start();
            },TaskCreationOptions.PreferFairness);

            task0.Start();  
            task0.Wait();

            Console.WriteLine("主线程");

            Console.ReadLine();
        }
    }
}
